<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.4: http://docutils.sourceforge.net/" />
<title>Virtualization</title>
<meta name="author" content="Philip Levis" />
<style type="text/css">

/*
:Author: David Goodger
:Contact: goodger@users.sourceforge.net
:date: $Date: 2009-02-03 23:07:32 $
:version: $Revision: 1.9 $
:copyright: This stylesheet has been placed in the public domain.

Default cascading style sheet for the HTML output of Docutils.
*/
body {
  font-family: Times;
  font-size: 16px;
}

.first {
  margin-top: 0 ! important }

.last {
  margin-bottom: 0 ! important }

.hidden {
  display: none }

a.toc-backref {
  text-decoration: none ;
  color: black }

blockquote.epigraph {
  margin: 2em 5em ; }

dd {
  margin-bottom: 0.5em }

div.abstract {
  margin: 2em 5em }

div.abstract p.topic-title {
  font-weight: bold ;
  text-align: center }

div.attention, div.caution, div.danger, div.error, div.hint,
div.important, div.note, div.tip, div.warning, div.admonition {
  margin: 2em ;
  border: medium outset ;
  padding: 1em }

div.attention p.admonition-title, div.caution p.admonition-title,
div.danger p.admonition-title, div.error p.admonition-title,
div.warning p.admonition-title {
  color: red ;
  font-weight: bold ;
  font-family: sans-serif }

div.hint p.admonition-title, div.important p.admonition-title,
div.note p.admonition-title, div.tip p.admonition-title,
div.admonition p.admonition-title {
  font-weight: bold ;
  font-family: sans-serif }

div.dedication {
  margin: 2em 5em ;
  text-align: center ;
  font-style: italic }

div.dedication p.topic-title {
  font-weight: bold ;
  font-style: normal }

div.figure {
  margin-left: 2em }

div.footer, div.header {
  font-size: smaller }

div.line-block {
  display: block ;
  margin-top: 1em ;
  margin-bottom: 1em }

div.line-block div.line-block {
  margin-top: 0 ;
  margin-bottom: 0 ;
  margin-left: 1.5em }

div.sidebar {
  margin-left: 1em ;
  border: medium outset ;
  padding: 0em 1em ;
  background-color: #ffffee ;
  width: 40% ;
  float: right ;
  clear: right }

div.sidebar p.rubric {
  font-family: sans-serif ;
  font-size: medium }

div.system-messages {
  margin: 5em }

div.system-messages h1 {
  color: red }

div.system-message {
  border: medium outset ;
  padding: 1em }

div.system-message p.system-message-title {
  color: red ;
  font-weight: bold }

div.topic {
  margin: 2em }

h1 {
  font-family: Arial, sans-serif;
  font-size: 20px;
}

h1.title {
 text-align: center;
 font-size: 32px;
}

h2 {
 font-size: 16px;
 font-family: Arial, sans-serif;
}

h2.subtitle {
  text-align: center }

h3 {
 font-size: 12px;
 font-family: Arial, sans-serif;
}

hr {
  width: 75% }

ol.simple, ul.simple {
  margin-bottom: 1em }

ol.arabic {
  list-style: decimal }

ol.loweralpha {
  list-style: lower-alpha }

ol.upperalpha {
  list-style: upper-alpha }

ol.lowerroman {
  list-style: lower-roman }

ol.upperroman {
  list-style: upper-roman }

p.attribution {
  text-align: right ;
  margin-left: 50% }

p.caption {
  font-style: italic }

p.credits {
  font-style: italic ;
  font-size: smaller }

p.label {
  white-space: nowrap }

p.rubric {
  font-weight: bold ;
  font-size: larger ;
  color: maroon ;
  text-align: center }

p.sidebar-title {
  font-family: sans-serif ;
  font-weight: bold ;
  font-size: larger }

p.sidebar-subtitle {
  font-family: sans-serif ;
  font-weight: bold }

p.topic-title {
  font-weight: bold }

pre.address {
  margin-bottom: 0 ;
  margin-top: 0 ;
  font-family: serif ;
  font-size: 100% }

pre.line-block {
  font-family: serif ;
  font-size: 100% }

pre.literal-block, pre.doctest-block {
  margin-left: 2em ;
  margin-right: 2em ;
  background-color: #eeeeee;
  border-color: #000000;
  border-width: thin; 
  font-size: 14px
}

span.classifier {
  font-family: sans-serif ;
  font-style: oblique }

span.classifier-delimiter {
  font-family: sans-serif ;
  font-weight: bold }

span.interpreted {
  font-family: sans-serif }

span.option {
  white-space: nowrap }

span.option-argument {
  font-style: italic }

span.pre {
  white-space: pre }

span.problematic {
  color: red }

table {
  margin-top: 0.5em ;
  margin-bottom: 0.5em }

table.citation {
  border-left: solid thin gray ;
  padding-left: 0.5ex }

table.docinfo {
  margin: 2em 4em;
}

table.footnote {
  border-left: solid thin black ;
  padding-left: 0.5ex }

td, th {
  padding-left: 0.5em ;
  padding-right: 0.5em ;
  vertical-align: top }

th.docinfo-name, th.field-name {
  font-weight: bold ;
  text-align: left ;
  white-space: nowrap;
  }

h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt {
  font-size: 100% }

tt {}

ul.auto-toc {
  list-style-type: none }

</style>
</head>
<body>
<div class="document" id="virtualization">
<h1 class="title">Virtualization</h1>
<table class="docinfo" frame="void" rules="none">
<col class="docinfo-name" />
<col class="docinfo-content" />
<tbody valign="top">
<tr class="field"><th class="docinfo-name">TEP:</th><td class="field-body">110</td>
</tr>
<tr class="field"><th class="docinfo-name">Group:</th><td class="field-body">Core Working Group</td>
</tr>
<tr class="field"><th class="docinfo-name">Type:</th><td class="field-body">Documentary</td>
</tr>
<tr><th class="docinfo-name">Status:</th>
<td>Draft</td></tr>
<tr class="field"><th class="docinfo-name">TinyOS-Version:</th><td class="field-body">2.x</td>
</tr>
<tr><th class="docinfo-name">Author:</th>
<td>Philip Levis</td></tr>
<tr class="field"><th class="docinfo-name">Draft-Created:</th><td class="field-body">20-Jun-2005</td>
</tr>
<tr class="field"><th class="docinfo-name">Draft-Version:</th><td class="field-body">1.5</td>
</tr>
<tr class="field"><th class="docinfo-name">Draft-Modified:</th><td class="field-body">2006-12-12</td>
</tr>
<tr class="field"><th class="docinfo-name">Draft-Discuss:</th><td class="field-body">TinyOS Developer List &lt;tinyos-devel at mail.millennium.berkeley.edu&gt;</td>
</tr>
</tbody>
</table>
<div class="note">
<p class="first admonition-title">Note</p>
<p class="last">This memo documents a part of TinyOS for the TinyOS Community, and
requests discussion and suggestions for improvements.  Distribution
of this memo is unlimited. This memo is in full compliance with
TEP 1.</p>
</div>
<div class="section">
<h1><a id="abstract" name="abstract">Abstract</a></h1>
<p>This memo desribes how TinyOS 2.0 virtualizes common abstractions through
a combination of static allocation and runtime arbitration. It describes
the benefits and tradeoffs of this approach and how it is used in several
major abstractions.</p>
</div>
<div class="section">
<h1><a id="introduction" name="introduction">1. Introduction</a></h1>
<p>The TinyOS component model allows flexible composition, but that
flexibility is often limited by reasons which are not explicitly
stated in components. These implicit assumptions can manifest as buggy
behavior. In TinyOS 1.x, on the Telos platform, if a program
simultaneously initializes non-volatile storage and the radio, one of
them will fail: a program has to initialize them serially. They can
also manifest as compile-time errors: if two separate communication
services happen to receive packets of the same AM type, the nesC
compiler will issue a warning due to the buffer swap semantics.</p>
<p>On one hand, the flexbility components provide allows expert users to
build complex and intricate applications. On the other, it can make
managing complexity and intricacy very difficult when building very
simple and basic applications. To promote this latter class of
development, TinyOS 2.x has the notion of &quot;distributions,&quot; which are
collections of system abstractions that are designed to be used
together. As long as a user implements an application in terms of the
distribution, the underlying components will operate correctly and
there will be no unforseen failures.</p>
<p>This memo documents an example distribution, named OSKI (Operating
System Key Interfaces). It describes the services OSKI provides and
how their implementations are structured to simplify application
writing.</p>
</div>
<div class="section">
<h1><a id="distributions" name="distributions">2. Distributions</a></h1>
<p>A distribution presents <em>services</em> to the programmer. A service is a
set of generic (instantiable) components that represent API
abstractions. To use an abstraction, a programmer instantiates the
generic. For example, OSKI has the <tt class="docutils literal"><span class="pre">AMSenderC</span></tt> abstraction for
sending active messages. The AMSender generic component takes a single
parameter, the AM type. For example, if a programmer wants a component
named AppM to send active messages of type 32, the configuration would
look something like this:</p>
<div class="line-block">
<div class="line">configuration AppC {}</div>
<div class="line">implementation {</div>
<div class="line-block">
<div class="line">components AppM, new AMSenderC(32);</div>
<div class="line">AppM.AMSend -&gt; AMSenderC;</div>
</div>
<div class="line">}</div>
</div>
<p>Services often present abstractions at a fine grain. For example, the
active message service has AMSender, AMReceiver, and AMSnooper, each
of which is a separate abstraction.</p>
<div class="section">
<h2><a id="controlling-a-service" name="controlling-a-service">2.1 Controlling a Service</a></h2>
<p>Every service has two abstractions: <tt class="docutils literal"><span class="pre">ServiceC</span></tt>, for powering it on
and off, and <tt class="docutils literal"><span class="pre">ServiceNotifierC</span></tt>, for learning when the service's
power state has changed. For example, active messages have the
<tt class="docutils literal"><span class="pre">AMServiceC</span></tt> and <tt class="docutils literal"><span class="pre">AMServiceNotifierC</span></tt> abstractions. A service
abstraction provides the <tt class="docutils literal"><span class="pre">Service</span></tt> interface</p>
<div class="line-block">
<div class="line">interface Service {</div>
<div class="line-block">
<div class="line">command void start();</div>
<div class="line">command void stop();</div>
<div class="line">command bool isRunning();</div>
</div>
<div class="line">}</div>
</div>
<p>while a notifier abstraction provides the <tt class="docutils literal"><span class="pre">ServiceNotify</span></tt> interface</p>
<div class="line-block">
<div class="line">interface ServiceNotify {</div>
<div class="line-block">
<div class="line">event void started();</div>
<div class="line">event void stopped();</div>
</div>
<div class="line">}</div>
</div>
<p>For example, if a routing layer wants to be able to turn the active
message layer on and off, then it needs to instantiate an AMServiceC.
However, many components may be using active messages and have their
own instances of AMServiceC; while routing might consider it
acceptable to turn off active messages, other components might
not. Therefore, a service abstraction does not necessarily represent
explicit control; instead, each service has a <em>policy</em> for how it
deals with control requests. When a service changes its activity
state, it MUST signal all instances of its ServiceNotifierC.</p>
<p>For example, the active messages service has an &quot;OR&quot; policy; the
service remains active if <em>any</em> of its ServiceC instances are in the
on state, and goes inactive if and only if <em>all</em> of its ServiceC
instances are in the off state. This is an example timeline for
active messages being used by two components, RouterA and RouterB:</p>
<ol class="arabic simple">
<li>System boots: active messages are off.</li>
<li>RouterA calls <tt class="docutils literal"><span class="pre">Service.start()</span></tt>. The AM layer is turned on.</li>
<li>All AMServiceNotifierC abstractions signal <tt class="docutils literal"><span class="pre">ServiceNotify.started().</span></tt></li>
<li>RouterB calls <tt class="docutils literal"><span class="pre">Service.start()</span></tt>.</li>
<li>RouterA calls <tt class="docutils literal"><span class="pre">Service.stop()</span></tt>. RouterB is still using active messages, so the layer stays on.</li>
<li>RouterB calls <tt class="docutils literal"><span class="pre">Service.stop()</span></tt>. The AM layer is turned off.</li>
<li>All AMServiceNotifierC abstractions signal <tt class="docutils literal"><span class="pre">ServiceNotify.stopped().</span></tt></li>
</ol>
<p>By default, a service that has a control interface MUST be off. For an
application to use the service, at least one component has to call
<tt class="docutils literal"><span class="pre">Service.start()</span></tt>.</p>
</div>
<div class="section">
<h2><a id="service-initialization" name="service-initialization">2.2 Service Initialization</a></h2>
<p>Because distributions are collections of services that are designed to
work together, they can avoid many of the common issues that arise
when composing TinyOS programs. For example, user code does not have
to initialize a service; this is done automatically by the
distribution.  If a user component instantiates a service abstraction,
the distribution MUST make sure that the service is properly
initialized. Section 4 goes into an example implementation of how a
distribution can achieve this.</p>
</div>
</div>
<div class="section">
<h1><a id="oski-services" name="oski-services">3. OSKI Services</a></h1>
<p>This section briefly describes the services that OSKI, an example
distribution provides. It is intended to give a feel for how a
distribution presents its abstractions.</p>
<div class="section">
<h2><a id="timers" name="timers">3.1 Timers</a></h2>
<p>OSKI provides timers at one fidelity: milliseconds. Timers do not have
a Service abstraction, as their use implicitly defines whether the
service is active or not (the timer service is off if there are no
pending timers).  The <tt class="docutils literal"><span class="pre">OSKITimerMsC</span></tt> component provides the
abstraction: it provides a single interface, <tt class="docutils literal"><span class="pre">Timer&lt;TMilli&gt;</span></tt>.</p>
<p>This is an example code snippet for instantiating a timer in a
configuration:</p>
<div class="line-block">
<div class="line">configuration ExampleC {</div>
<div class="line-block">
<div class="line">uses interface Timer&lt;TMilli&gt;;</div>
</div>
<div class="line">}</div>
<div class="line"><br /></div>
<div class="line">configuration TimerExample {}</div>
<div class="line">implementation {</div>
<div class="line-block">
<div class="line">components ExampleC, new OSKITimerMsC() as T;</div>
<div class="line">ExampleC.Timer -&gt; T;</div>
</div>
<div class="line">}</div>
</div>
</div>
<div class="section">
<h2><a id="active-messages" name="active-messages">3.2 Active Messages</a></h2>
<p>OSKI provides four functional active messaging abstractions:
<tt class="docutils literal"><span class="pre">AMSender</span></tt>, <tt class="docutils literal"><span class="pre">AMReceiver</span></tt>, <tt class="docutils literal"><span class="pre">AMSnooper</span></tt>, and
<tt class="docutils literal"><span class="pre">AMSnoopingReceiver</span></tt>. Each one takes an <tt class="docutils literal"><span class="pre">am_id_t</span></tt> as a parameter,
indicating the AM type. Following the general TinyOS 2.x approach to
networking, all active message abstractions provide the <tt class="docutils literal"><span class="pre">Packet</span></tt> and
<tt class="docutils literal"><span class="pre">AMPacket</span></tt> interfaces.</p>
<dl class="docutils">
<dt>AMSender</dt>
<dd>This abstraction is for sending active messages. In addition to Packet
and AMPacket, it provides the AMSend interface.</dd>
<dt>AMReceiver</dt>
<dd>This abstraction is for receiving active messages addressed to the
node or to the broadcast address. In addition to Packet and AMPacket,
it provides the Receive interface.</dd>
<dt>AMSnooper</dt>
<dd>This abstraction is for receiving active messages addressed to other
nodes (&quot;snooping&quot; on traffic). In addition to Packet and AMPacket,
it provides the Receive interface.</dd>
<dt>AMSnoopingReceiver</dt>
<dd>A union of the functionality of AMReceiver and AMSnooper, this
abstraction allows a component to receive <em>all</em> active messages
that it hears. The AMPacket interface allows a component to determine
whether such a message is destined for it. In addition to
Packet and AMPacket, this component provides the Receive interface.</dd>
</dl>
<p>This snippet of code is an example of a configuration that composes a
routing layer with needed active message abstractions. This
implementation snoops on data packets sent by other nodes to improve
its topology formation:</p>
<div class="line-block">
<div class="line">configuration RouterC {</div>
<div class="line-block">
<div class="line">uses interface AMSend as DataSend;</div>
<div class="line">uses interface AMSend as ControlSend;</div>
<div class="line">uses interface Receive as DataReceive;</div>
<div class="line">uses interface Receive as BeaconReceive;</div>
</div>
<div class="line">}</div>
<div class="line"><br /></div>
<div class="line">configuration RoutingExample {</div>
<div class="line-block">
<div class="line">components RouterC;</div>
<div class="line">components new AMSender(5) as CSender;</div>
<div class="line">components new AMSender(6) as DSender;</div>
<div class="line">components new AMReceiver(5) as CReceiver;</div>
<div class="line">components new AMSnoopingReceiver(6) as DReceiver;</div>
<div class="line"><br /></div>
<div class="line">RouterC.DataSend -&gt; DSender;</div>
<div class="line">RouterC.ControlSend -&gt; CSender;</div>
<div class="line">RouterC.DataReceive -&gt; DReceiver;</div>
<div class="line">RouterC.ControlReceive -&gt; CReceiver;</div>
</div>
<div class="line">}</div>
</div>
<p>The active messages layer has control abstractions, named <tt class="docutils literal"><span class="pre">AMServiceC</span></tt>
and <tt class="docutils literal"><span class="pre">AMServiceNotifierC</span></tt>. Active messages follow an OR policy.</p>
</div>
<div class="section">
<h2><a id="broadcasts" name="broadcasts">3.3 Broadcasts</a></h2>
<p>In addition to active messages, OSKI provides a broadcasting service.
Unlike active messages, which are addressed in terms of AM addresses,
broadcasts are address-free. Broadcast communication has two
abstractions: <tt class="docutils literal"><span class="pre">BroadcastSenderC</span></tt> and <tt class="docutils literal"><span class="pre">BroadcastReceiverC</span></tt>, both of
which take a parameter, a broadcast message type. This parameter is
similar to the AM type in active messages. Both abstractions provide
the Packet interface. The broadcast service has control abstractions,
named <tt class="docutils literal"><span class="pre">BroadcastServiceC</span></tt> and <tt class="docutils literal"><span class="pre">BroadcastServiceNotifierC</span></tt>, which
follow an OR policy.</p>
</div>
<div class="section">
<h2><a id="tree-collection-convergecast" name="tree-collection-convergecast">3.4 Tree Collection/Convergecast</a></h2>
<p><strong>NOTE: These services are not supported as of the 2.x prerelease.
They will be supported by the first full release.</strong></p>
<p>OSKI's third communication service is tree-based collection routing.
This service has four abstractions:</p>
<dl class="docutils">
<dt>CollectionSenderC</dt>
<dd>This abstraction is for sending packets up the collection tree,
to the collection root. It provides the Send and Packet interfaces.</dd>
<dt>CollectionReceiverC</dt>
<dd>This abstraction is for a collection end-point (a tree root). It
provides the Receive, Packet, and CollectionPacket interfaces.</dd>
<dt>CollectionInterceptorC</dt>
<dd>This abstraction represents a node's ability to view and possibly
suppress packets it has received for forwarding. It provides
the Intercept, CollectionPacket, and Packet interfaces.</dd>
<dt>CollectionSnooperC</dt>
<dd>This abstraction allows a node to overhear routing packets
sent to other nodes to forward. It provides the Receive,
CollectionPacket, and Packet interfaces.</dd>
</dl>
<p>All of the collection routing communication abstractions take a
parameter, similar to active messages and broadcasts, so multiple
components can independelty use collection routing. In addition to
communication, collection routing has an additional abstraction:</p>
<dl class="docutils">
<dt>CollectionControlC</dt>
<dd>This abstraction controls whether a node is a collection root
or not.</dd>
</dl>
<p>Finally, collection routing has <tt class="docutils literal"><span class="pre">CollectionServiceC</span></tt> and
<tt class="docutils literal"><span class="pre">CollectionServiceNotifierC</span></tt> abstractions, which follow an OR
policy.</p>
</div>
<div class="section">
<h2><a id="uart" name="uart">3.5 UART</a></h2>
<p><strong>NOTE: These services are not supported as of the 2.x prerelease.
They will be supported by the first full release.
They will be fully defined pending discussion/codification of
UART interfaces.</strong></p>
</div>
</div>
<div class="section">
<h1><a id="oski-service-structure-and-design" name="oski-service-structure-and-design">4. OSKI Service Structure and Design</a></h1>
<p>Presenting services through abstractions hides the underlying wiring
details and gives a distribution a great deal of implementation
freedom. One issue that arises, however, is initialization. If a user
component instantiates a service, then a distribution MUST make sure
the service is initialized properly. OSKI achieves this by
encapsulating a complete service as a working component; abstractions
export the service's interfaces.</p>
<div class="section">
<h2><a id="example-timers" name="example-timers">4.1 Example: Timers</a></h2>
<p>For example, the timer service provides a single abstraction,
OskiTimerMilliC, which is a generic component. OskiTimerMilliC provides a
single instance of the Timer&lt;TMilli&gt; interface. It is implemented as a
wrapper around the underlying timer service, a component named
<tt class="docutils literal"><span class="pre">TimerMilliImplP</span></tt>, which provides a parameterized interface and
follows the Service Instance design pattern[sipattern]_:</p>
<div class="line-block">
<div class="line">generic configuration OskiTimerMilliC() {</div>
<div class="line-block">
<div class="line">provides interface Timer&lt;TMilli&gt;;</div>
</div>
<div class="line">}</div>
<div class="line">implementation {</div>
<div class="line-block">
<div class="line">components TimerMilliImplP;</div>
<div class="line">Timer = TimerMilliImplP.TimerMilli[unique(&quot;TimerMilliC.TimerMilli&quot;)];</div>
</div>
<div class="line">}</div>
</div>
<p>TimerMilliImplP is a fully composed and working service. It takes
a platform's timer implementation and makes sure it is initialized through
the TinyOS boot sequence[boot]_:</p>
<div class="line-block">
<div class="line">configuration TimerMilliImplP {</div>
<div class="line-block">
<div class="line">provides interface Timer&lt;TMilli&gt; as TimerMilli[uint8_t id];</div>
</div>
<div class="line">}</div>
<div class="line">implementation {</div>
<div class="line-block">
<div class="line">components TimerMilliC, Main;</div>
<div class="line">Main.SoftwareInit -&gt; TimerMilliC;</div>
<div class="line">TimerMilli = TimerMilliC;</div>
</div>
<div class="line">}</div>
</div>
<p>This composition means that if any component instantiates a timer,
then TimerMilliImplP will be included in the component graph. If
TimerMilliImplP is included, the TimerMilliP (the actual platform HIL
implementation) will be properly initialized at system boot time. In
this case, the order of initialization isn't important; in cases where
there are services that have to be initialized in a particular
sequence to ensure proper ordering, the Impl components can
orchestrate that order. For example, a distribution can wire
Main.SoftwareInit to a DistributionInit component, which calls
sub-Inits in a certain order; when a service is included, it wires
itself to one of the sub-Inits.</p>
<p>The user does not have to worry about unique strings to manage the
underlying Service Instance pattern: the abstractions take care of
that.</p>
</div>
<div class="section">
<h2><a id="example-active-messages" name="example-active-messages">4.2 Example: Active Messages</a></h2>
<p>Active messaging reprsent a slightly more complex service, as it has
several abstractions and a control interface. However, it follows the
same basic pattern: abstractions are generics that export wirings to
the underlying service, named <tt class="docutils literal"><span class="pre">ActiveMessageImplP</span></tt>:</p>
<div class="line-block">
<div class="line">configuration ActiveMessageImplP {</div>
<div class="line-block">
<div class="line">provides {</div>
<div class="line-block">
<div class="line">interface SplitControl;</div>
<div class="line">interface AMSend[am_id_t id];</div>
<div class="line">interface Receive[am_id_t id];</div>
<div class="line">interface Receive as Snoop[am_id_t id];</div>
<div class="line">interface Packet;</div>
<div class="line">interface AMPacket;</div>
</div>
<div class="line">}</div>
</div>
<div class="line">}</div>
<div class="line"><br /></div>
<div class="line">implementation {</div>
<div class="line-block">
<div class="line">components ActiveMessageC, Main;</div>
<div class="line"><br /></div>
<div class="line">Main.SoftwareInit -&gt; ActiveMessageC;</div>
<div class="line"><br /></div>
<div class="line">SplitControl = ActiveMessageC;</div>
<div class="line">AMSend = ActiveMessageC;</div>
<div class="line">Receive = ActiveMessageC.Receive;</div>
<div class="line">Snoop = ActiveMessageC.Snoop;</div>
<div class="line">Packet = ActiveMessageC;</div>
<div class="line">AMPacket = ActiveMessageC;</div>
</div>
<div class="line">}</div>
</div>
<p>For example, this is the AMSender abstraction:</p>
<div class="line-block">
<div class="line">generic configuration AMSenderC(am_id_t AMId) {</div>
<div class="line-block">
<div class="line">provides {</div>
<div class="line-block">
<div class="line">interface AMSend;</div>
<div class="line">interface Packet;</div>
<div class="line">interface AMPacket;</div>
</div>
<div class="line">}</div>
</div>
<div class="line">}</div>
<div class="line"><br /></div>
<div class="line">implementation {</div>
<div class="line-block">
<div class="line">components ActiveMessageImplP as Impl;</div>
<div class="line"><br /></div>
<div class="line">AMSend = Impl.AMSend[AMId];</div>
<div class="line">Packet = Impl;</div>
<div class="line">AMPacket = Impl;</div>
</div>
<div class="line">}</div>
</div>
<p>AMReceiver is similar, except that it wires to the Receive interface,
while AMSnooper wires to the Snoop interface, and AMSnoopingReceiver
provides a single Receive that exports both Snoop and Receive (the
unidirectional nature of the Receive interface makes this simple to
achieve, as it represents only fan-in and no fan-out).</p>
<p>ActiveMessageImplP does not provide a Service interface; it provides
the SplitControl interface of the underlying active message
layer. OSKI layers a <em>ServiceController</em> on top of SplitControl. As
the active message service follows an OR policy, OSKI uses a
<tt class="docutils literal"><span class="pre">ServiceOrControllerM</span></tt>, which is a generic component with the
following signature:</p>
<div class="line-block">
<div class="line">generic module ServiceOrControllerM(char strID[]) {</div>
<div class="line-block">
<div class="line">provides {</div>
<div class="line-block">
<div class="line">interface Service[uint8_t id];</div>
<div class="line">interface ServiceNotify;</div>
</div>
<div class="line">}</div>
<div class="line">uses {</div>
<div class="line-block">
<div class="line">interface SplitControl;</div>
</div>
<div class="line">}</div>
</div>
<div class="line">}</div>
</div>
<p>ServiceOrControllerM follows the Service Instance pattern[sipattern];
it calls its underlying SplitControl based on the state of each of its
instances of the Service interface. The parameter denotes the string
used to generate the unique service IDs. The active messages service
controller implementation, AMServiceImplP, instantiates a
ServiceOrControllerM, wires it to ActiveMessageImplP:</p>
<div class="line-block">
<div class="line">configuration AMServiceImplP {</div>
<div class="line-block">
<div class="line">provides interface Service[uint8_t id];</div>
<div class="line">provides interface ServiceNotify;</div>
</div>
<div class="line">}</div>
<div class="line">implementation {</div>
<div class="line-block">
<div class="line">components ActiveMessageImplP;</div>
<div class="line">components new ServiceOrControllerM(&quot;AMServiceImplP.Service&quot;);</div>
<div class="line"><br /></div>
<div class="line">Service = ServiceOrControllerM;</div>
<div class="line">ServiceOrControllerM.SplitControl -&gt; ActiveMessageImplP;</div>
<div class="line">ServiceNotify = ServiceOrControllerM;</div>
</div>
<div class="line">}</div>
</div>
<p>AMServiceC then provides an instance of AMServiceImplP.Service:</p>
<div class="line-block">
<div class="line">generic configuration AMServiceC() {</div>
<div class="line-block">
<div class="line">provides interface Service;</div>
</div>
<div class="line">}</div>
<div class="line"><br /></div>
<div class="line">implementation {</div>
<div class="line-block">
<div class="line">components AMServiceImplP;</div>
<div class="line"><br /></div>
<div class="line">Service = AMServiceImplP.Service[unique(&quot;AMServiceImplP.Service&quot;)];</div>
</div>
<div class="line">}</div>
</div>
<p>Note that the two strings are the same, so that the uniqueCount() in
the ServiceOrControllerM is correct based on the number of instances
of AMServiceC. As with timers, encapsulating the service instance
pattern in generic components relieves the programmer of having to
deal with unique strings, a common source of bugs in TinyOS 1.x code.</p>
</div>
<div class="section">
<h2><a id="oski-requirements" name="oski-requirements">4.3 OSKI Requirements</a></h2>
<p>OSKI is a layer on top of system components: it presents a more
usable, less error-prone, and simpler interface to common TinyOS
functionality. For OSKI to work properly, a platform MUST be compliant
with the following TEPs:</p>
<blockquote>
o TEP 102: Timers
o TEP 106: Schedulers and Tasks
o TEP 107: TinyOS 2.x Boot Sequence
o TEP 1XX: Active Messages
o TEP 1XX: Collection Routing</blockquote>
<p>Not following some of these TEPS MAY lead to OSKI services being
inoperable, exhibit strange behavior, or being uncompilable.</p>
</div>
</div>
<div class="section">
<h1><a id="distribution-interfaces" name="distribution-interfaces">5. Distribution Interfaces</a></h1>
<p>The basic notion of a distribution is that it provides a self-contained,
tested, and complete (for an application domain) programming interface
to TinyOS. Layers can be added on top of a distribution, but as a
distribution is a self-contained set of abstractions, adding new
services can lead to failures. A distribution represents a hard line
above which all other code operates. One SHOULD NOT add new services,
as they can disrupt the underlying organization. Of course, one MAY
create a new distribution that extends an existing one, but this is
in and of itself a new distribution.</p>
<p>Generally, as distributions are intended to be higher-level abstractions,
they SHOULD NOT provide any asynchronous (async) events. They can,
of course, provide async commands. The idea is that no code written on
top of a distribution should be asynchronous, due to the complexity
introduced by having to manage concurrency. Distributions are usually
platform independent; if an application needs async events, then
chances are it is operating close to the hardware, and so is not
platform independent.</p>
</div>
<div class="section">
<h1><a id="author-s-address" name="author-s-address">6. Author's Address</a></h1>
<div class="line-block">
<div class="line">Philip Levis</div>
<div class="line">467 Soda Hall</div>
<div class="line">UC Berkeley</div>
<div class="line">Berkeley, CA 94720</div>
<div class="line"><br /></div>
<div class="line">phone - +1 510 290 5283</div>
<div class="line"><br /></div>
<div class="line">email - <a class="reference" href="mailto:pal&#64;cs.berkeley.edu">pal&#64;cs.berkeley.edu</a></div>
</div>
</div>
<div class="section">
<h1><a id="citations" name="citations">7. Citations</a></h1>
<table class="docutils citation" frame="void" id="rst" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a name="rst">[rst]</a></td><td>reStructuredText Markup Specification. &lt;<a class="reference" href="http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html">http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html</a>&gt;</td></tr>
</tbody>
</table>
<table class="docutils citation" frame="void" id="sipattern" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a name="sipattern">[sipattern]</a></td><td>The Service Instance Pattern. In <em>Software Design Patterns for TinyOS.</em> David Gay, Philip Levis, and David Culler. Published in Proceedings of the ACM SIGPLAN/SIGBED 2005 Conference on Languages, Compilers, and Tools for Embedded Systems (LCTES'05).</td></tr>
</tbody>
</table>
<table class="docutils citation" frame="void" id="boot" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a name="boot">[boot]</a></td><td>TEP 107: TinyOS 2.x Boot Sequence.</td></tr>
</tbody>
</table>
</div>
</div>
</body>
</html>
